import {
  BarChart,
  EffectScatterChart,
  GaugeChart,
  LineChart,
  MapChart,
  PictorialBarChart,
  PieChart,
  RadarChart,
} from 'echarts/charts'
import {
  GridComponent,
  LegendComponent,
  TitleComponent,
  TooltipComponent,
} from 'echarts/components'
import { type ECharts, type EChartsCoreOption, init, registerTheme, throttle, use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { onBeforeUnmount, onMounted, ref } from 'vue'

import dark from './chart-dark-theme'

import elementResizeDetectorMaker from 'element-resize-detector'

use([
  CanvasRenderer,
  PieChart,
  BarChart,
  LineChart,
  RadarChart,
  MapChart,
  GaugeChart,
  EffectScatterChart,
  PictorialBarChart,
  GridComponent,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
])

// 暗黑主题
registerTheme('dark', dark)

export interface EChartsOption extends EChartsCoreOption {
}

const erd = elementResizeDetectorMaker()

export default function useEcharts(theme: string = 'dark', autoresize: boolean = true, debug: boolean = false) {
  const chartRef = ref<HTMLDivElement>()
  let chartInstance: ECharts | null = null

  function setOption(option: EChartsCoreOption) {
    chartInstance?.setOption(option)
  }

  const resize = throttle(() => {
    if (debug)
      console.log('resize')
    chartInstance?.resize({
      animation: {
        duration: 0,
        easing: 'linear',
      },
    })
  }, 60, true) as any

  function doResize(options: any = {
    animation: {
      duration: 600,
      easing: 'cubicInOut',
    },
  }) {
    chartInstance?.resize(options)
  }

  function hideLoading() {
    chartInstance?.hideLoading()
  }
  function showLoading() {
    chartInstance?.showLoading()
  }

  function addListener() {
    if (chartRef.value) {
      erd.listenTo(chartRef.value, resize)
    }
  }

  function removeListener() {
    if (chartRef.value) {
      erd.removeListener(chartRef.value, resize)
    }
  }

  onMounted(() => {
    if (chartRef.value) {
      chartInstance = init(chartRef.value, theme)
      if (autoresize) {
        addListener()
      }
    }
  })

  onBeforeUnmount(() => {
    if (autoresize) {
      removeListener()
    }
    chartInstance?.dispose()
    chartInstance = null
  })

  return { chartRef, setOption, resize, doResize, registerTheme, hideLoading, showLoading }
}
